<!DOCTYPE html>
<html>
<head>
    <style>
        .matrix {
            display: inline-block;
            border: 2px solid #333;
            margin: 20px;
            background: #f8f9fa;
        }
        .row {
            display: flex;
        }
        .cell {
            width: 60px;
            height: 60px;
            border: 1px solid #ddd;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 20px;
            transition: all 0.6s;
            background: #fff;
        }
        .active {
            background: #4CAF50 !important;
            transform: scale(1.1);
            z-index: 1;
        }
        .swapping {
            background: #2196F3 !important;
        }
        .controls {
            margin: 20px;
            text-align: center;
        }
        #matrixInput {
            width: 300px;
            padding: 8px;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div class="controls">
        <textarea id="matrixInput" rows="4">[[1,2,3],[4,5,6],[7,8,9]]</textarea><br>
        <button onclick="reset()">重置</button>
        <button onclick="togglePause()">暂停/继续</button>
        速度: <input type="range" id="speed" min="100" max="1000" value="500">
    </div>
    <div id="matrixContainer"></div>

    <script>
        let isPaused = false;
        let animationQueue = [];
        let currentStep = 0;
        let speed = 500;

        function createMatrix(matrix) {
            const container = document.getElementById('matrixContainer');
            container.innerHTML = '';
            
            matrix.forEach((row, i) => {
                const rowDiv = document.createElement('div');
                rowDiv.className = 'row';
                row.forEach((num, j) => {
                    const cell = document.createElement('div');
                    cell.className = 'cell';
                    cell.textContent = num;
                    cell.dataset.pos = `${i}-${j}`;
                    rowDiv.appendChild(cell);
                });
                container.appendChild(rowDiv);
            });
        }

        async function animateRotation() {
            const matrix = JSON.parse(document.getElementById('matrixInput').value);
            const n = matrix.length;
            
            // 转置动画
            for (let i = 0; i < n; i++) {
                for (let j = i; j < n; j++) {
                    await animateSwap(i, j, j, i);
                }
            }
            
            // 翻转动画
            for (let i = 0; i < n; i++) {
                for (let j = 0; j < n/2; j++) {
                    await animateSwap(i, j, i, n-1-j);
                }
            }
        }

        async function animateSwap(i1, j1, i2, j2) {
            const cell1 = document.querySelector(`[data-pos="${i1}-${j1}"]`);
            const cell2 = document.querySelector(`[data-pos="${i2}-${j2}"]`);
            
            // 高亮交换元素
            cell1.classList.add('active');
            cell2.classList.add('swapping');
            await delay();
            
            // 交换位置动画
            const temp = cell1.textContent;
            cell1.textContent = cell2.textContent;
            cell2.textContent = temp;
            
            // 重置样式
            cell1.classList.remove('active');
            cell2.classList.remove('swapping');
            await delay();
        }

        function delay() {
            return new Promise(resolve => {
                if (!isPaused) setTimeout(resolve, speed);
            });
        }

        function reset() {
            isPaused = false;
            createMatrix(JSON.parse(document.getElementById('matrixInput').value));
            animateRotation();
        }

        function togglePause() {
            isPaused = !isPaused;
            if (!isPaused) animateRotation();
        }

        // 初始化
        document.getElementById('speed').addEventListener('input', (e) => {
            speed = 1000 - e.target.value;
        });
        reset();
    </script>
</body>
</html>
